home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / PCW_C.ARJ / PLMENU.C < prev    next >
C/C++ Source or Header  |  1991-12-16  |  13KB  |  337 lines

  1. /***************************************************************/
  2. /* File Id.                     PLMENU.C                       */
  3. /* Author.                      Stan Milam.                    */
  4. /* Date Written.                06 Oct 1990.                   */
  5. /*                                                             */
  6. /*              (c) Copyright 1990 by Stan Milam.              */
  7. /*                                                             */
  8. /* The code here will support a list menu.  A list menu is one */
  9. /* where the menu selections are a list of strings and the menu*/
  10. /* function returns an integer value indicating which string   */
  11. /* value was selected.                                         */
  12. /*                                                             */
  13. /***************************************************************/
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include "pcw.i"
  19. #include "pcwproto.h"
  20. #include "menu.h"
  21. #include "keys.h"
  22.  
  23. /* Internal function prototypes */
  24.  
  25. static void move_bar_down  ( PICKLIST *menu, int flag );
  26. static void move_bar_up    ( PICKLIST *menu, int flag );
  27. static int  do_mouse_move  ( int row, int col, PICKLIST *menu);
  28. /* */
  29. /***************************************************************/
  30. /*                       make_pick_list()                      */
  31. /*                                                             */
  32. /* This function will initialize the pick list menu by alloc-  */
  33. /* ating a window, putting in the title, and putting as manu of*/
  34. /* string selections in the pick list window as possible.      */
  35. /*                                                             */
  36. /* Returns: Pointer to window, or NULL for an error.           */
  37. /*                                                             */
  38. /***************************************************************/
  39.  
  40. WNDPTR *make_pick_list(PICKLIST *menu) {
  41.  
  42.      char     **wrk;
  43.      MENU_WND *pwnd;
  44.      int      row, cols, rows;
  45.      int      urow, ucol, lrow, lcol;
  46.      int      fcolor, bcolor, cfclr, cbclr;
  47.  
  48.      pwnd = &menu -> plwnd;
  49.  
  50. /*               functions yet to be written
  51.      save_btype = get_border_type();
  52.      get_border_color(&bfclr, &bbclr);
  53.      get_title_color(&tfclr, &tbclr);
  54. */
  55.      menu -> bar_pos = 0;
  56.      urow = pwnd -> urow; ucol = pwnd -> ucol;
  57.      lrow = pwnd -> lrow; lcol = pwnd -> lcol;
  58.      fcolor = pwnd -> fcolor; bcolor = pwnd -> bcolor;
  59.      cfclr = pwnd -> cfclr; cbclr = pwnd -> cbclr;
  60.  
  61.      setborder(pwnd->btype);
  62.      titlecolor(pwnd->tfclr, pwnd->tbclr);
  63.      bordercolor(pwnd->bfclr, pwnd->bbclr);
  64.  
  65.      pwnd -> wnd = wframe(urow, ucol, lrow, lcol, fcolor, bcolor);
  66.  
  67.      if (pwnd -> wnd == NULL) return ( NULL );
  68.  
  69.      urow = pwnd -> urow = pwnd->wnd->urow;
  70.      ucol = pwnd -> ucol = pwnd->wnd->ucol;
  71.      lrow = pwnd -> lrow = pwnd->wnd->lrow;
  72.      lcol = pwnd -> lcol = pwnd->wnd->lcol;
  73.      rows = (lrow - urow) - 1;
  74.  
  75.      wtitle(pwnd -> wnd, pwnd->tvloc, pwnd->thloc, pwnd->title);
  76.  
  77.      row = 1; wrk = &menu -> list[ menu -> off ];
  78.      while ( *wrk && row <= rows ) {
  79.            wputs(pwnd -> wnd, row, 2, *wrk);
  80.            wrk++;
  81.            row++;
  82.      }
  83.  
  84.      cols = (pwnd -> lcol - pwnd -> ucol) - 1;
  85.      w_chg_attr(pwnd->wnd, 1+menu->bar_pos,1, cfclr, cbclr,cols);
  86.      qputchar(urow+1, ucol, pwnd -> bfclr, pwnd -> bbclr, 24);
  87.      qputchar(urow+1, lcol, pwnd -> bfclr, pwnd -> bbclr, 25);
  88.  
  89.      return ( pwnd -> wnd );
  90. }
  91. /*   */
  92. /***************************************************************/
  93. /*                        get_pick_list()                      */
  94. /*                                                             */
  95. /* This function will handle the the actions of the user when  */
  96. /* picking an item from the pick list.  Handles MOUSE and key- */
  97. /* board action.                                               */
  98. /*                                                             */
  99. /* Returns: an integer value that is the ordinal value of the  */
  100. /* positon of the item in the list, or -1 if ESC was pressed.  */
  101. /*                                                             */
  102. /***************************************************************/
  103.  
  104. int get_pick_list(PICKLIST *menu) {
  105.  
  106.     int  ch, flag;
  107.     int  mrw, mcl, mstatus, off;
  108.     MENU_WND *mwnd;
  109.  
  110.     mwnd = &menu -> plwnd;
  111.     if (mpresent) hide_mouse();
  112.     re_order(mwnd->wnd, NORMAL);
  113.     if (mpresent) show_mouse();
  114.  
  115.     for(;;) {
  116.  
  117.           flag = 0;
  118.           off = menu -> off;
  119.           ch = readkey();
  120.           switch ( ch ) {
  121.                  case LEFT_MOUSE_KEY :
  122.                     get_mpos(&mrw, &mcl, &mstatus);
  123.                     if ((mstatus = do_mouse_move(mrw, mcl, menu)) > -1)
  124.                         return (mstatus);
  125.                     break;
  126.                  case ESC            :
  127.                  case RITE_MOUSE_KEY :
  128.                     return -1;
  129.                  case ENTER          :
  130.                  case BOTH_MOUSE_KEY :
  131.                     return off;
  132.                   case PGDN          :
  133.                     flag = 1;
  134.                  case DOWNARROW      :
  135.                     move_bar_down( menu, flag );
  136.                     break;
  137.                   case PGUP          :
  138.                     flag = 1;
  139.                  case UPARROW        :
  140.                     move_bar_up( menu, flag );
  141.                     break;
  142.           }
  143.     }
  144. #ifndef __TURBOC__
  145.       return ( 0 );
  146. #endif
  147. }
  148. /* */
  149. /***************************************************************/
  150. /*                        move_bar_down()                      */
  151. /*                                                             */
  152. /* This code isolates the logic necessary to move the lightbar */
  153. /* down or scroll the screen up, whatever is needed.           */
  154. /*                                                             */
  155. /* Returns: Nothing.                                           */
  156. /*                                                             */
  157. /***************************************************************/
  158.  
  159. static void move_bar_down( PICKLIST *menu, int flag ) {
  160.  
  161.      char     **wrk;
  162.      WNDPTR   *wnd;
  163.      MENU_WND *pwnd;
  164.      int      barpos, off, rows, cols, lcnt;
  165.      int      fcolor, bcolor, cfclr, cbclr, row;
  166.  
  167. /* Dereference everything to make it easier to work with */
  168.  
  169.      pwnd   = &menu -> plwnd;
  170.      wrk    = menu -> list;
  171.      barpos = menu -> bar_pos; off = menu -> off;
  172.      cfclr  = pwnd -> cfclr; cbclr = pwnd -> cbclr;
  173.      fcolor = pwnd -> fcolor; bcolor = pwnd -> bcolor;
  174.  
  175.      wnd = pwnd -> wnd;
  176.      rows = (wnd -> lrow - wnd -> urow) - 1;
  177.      cols = (wnd -> lcol - wnd -> ucol) - 1;
  178.      if ( flag ) {
  179.           for ( lcnt = -1; *wrk; wrk++, lcnt++);
  180.           if ( off + rows - barpos > lcnt ) flag = 0;
  181.      }
  182.      if ( flag ) {
  183.           if ( mpresent ) hide_mouse();
  184.           off += rows - barpos;
  185.           wrk = &menu -> list[ off ];
  186.           clr_wnd( wnd, 1 );
  187.           for ( row = 1; *wrk && row <= rows; wrk++, row++ )
  188.                 wputs( wnd, row, 2, *wrk);
  189.           barpos = 0;
  190.           w_chg_attr(wnd, barpos + 1, 1, cfclr, cbclr, cols);
  191.      }
  192.      else {
  193.           wrk = menu -> list;
  194.           if ( wrk[off + 1] == NULL ) return;
  195.           off++;
  196.           if (mpresent) hide_mouse();
  197.           if ( barpos >= (rows-1)) {
  198.               w_chg_attr(wnd, barpos + 1, 1, fcolor, bcolor, cols);
  199.               wscroll(wnd, 1, -1);
  200.               wputs(wnd, barpos + 1, 2, wrk[ off ]);
  201.               w_chg_attr(wnd, barpos + 1, 1, cfclr, cbclr, cols);
  202.           }
  203.           else {
  204.               barpos++;
  205.               w_chg_attr(wnd, barpos, 1, fcolor, bcolor, cols);
  206.               w_chg_attr(wnd, barpos + 1, 1, cfclr, cbclr, cols);
  207.           }
  208.      }
  209.      menu -> off = off; menu -> bar_pos = barpos;
  210.      if ( mpresent ) show_mouse();
  211. }
  212. /* */
  213. /***************************************************************/
  214. /*                       move_bar_up()                         */
  215. /*                                                             */
  216. /* This function isolates the code to move the lightbar up or  */
  217. /* scrolling the list which ever occurs.                       */
  218. /*                                                             */
  219. /* Returns: Nothing.                                           */
  220. /*                                                             */
  221. /***************************************************************/
  222.  
  223. static void move_bar_up( PICKLIST *menu, int flag ) {
  224.  
  225.      char     **wrk;
  226.      WNDPTR   *wnd;
  227.      MENU_WND *pwnd;
  228.      int      barpos, off, rows, cols,row;
  229.      int      fcolor, bcolor, cfclr, cbclr;
  230.  
  231. /* Dereference everything to make it easier to work with */
  232.  
  233.      pwnd   = &menu -> plwnd;
  234.      wrk    = menu -> list;
  235.      off    = menu -> off;
  236.      barpos = menu -> bar_pos;
  237.      cfclr  = pwnd -> cfclr; cbclr = pwnd -> cbclr;
  238.      fcolor = pwnd -> fcolor; bcolor = pwnd -> bcolor;
  239.  
  240.      wnd = pwnd -> wnd;
  241.      rows = (wnd -> lrow - wnd -> urow) - 1;
  242.      cols = (wnd -> lcol - wnd -> ucol) - 1;
  243.  
  244.      if ( flag )
  245.          if ( off - barpos - rows < 0 ) flag = 0;
  246.      if ( flag ) {
  247.          if ( mpresent ) hide_mouse();
  248.          off = off - barpos - rows;
  249.          wrk = &menu -> list[ off ];
  250.          clr_wnd( wnd, 1 );
  251.          for ( row = 1; *wrk && row <= rows; wrk++, row++ )
  252.               wputs( wnd, row, 2, *wrk );
  253.          barpos = 0;
  254.          w_chg_attr( wnd, barpos+1, 1, cfclr, cbclr, cols );
  255.      }
  256.      else {
  257.          if ( off < 1) return; else off--;
  258.          if (mpresent) hide_mouse();
  259.          if ( barpos ) {
  260.              w_chg_attr(wnd,barpos+1,1,fcolor,bcolor,cols);
  261.              w_chg_attr(wnd,barpos,1,cfclr,cbclr,cols);
  262.              barpos--;
  263.          }
  264.          else {
  265.              w_chg_attr(wnd,barpos+1,1,fcolor,bcolor,cols);
  266.              wscroll(wnd,1,1);
  267.              wputs(wnd,1,2,wrk[off]);
  268.              w_chg_attr(wnd,barpos+1,1,cfclr,cbclr,cols);
  269.          }
  270.      }
  271.      menu -> off = off;
  272.      menu -> bar_pos = barpos;
  273.      if ( mpresent ) show_mouse();
  274. }
  275. /* */
  276. /***************************************************************/
  277. /*                        do_mouse_move()                      */
  278. /*                                                             */
  279. /* This function isolates the code that moves the lightbar when*/
  280. /* the mouse comes into play.  Will determine if an item has   */
  281. /* been picked or if the user was moving the lightbar up or    */
  282. /* down.                                                       */
  283. /*                                                             */
  284. /* Returns -1 if no selection, or a value >= 0 if a selection  */
  285. /* was made.                                                   */
  286. /*                                                             */
  287. /***************************************************************/
  288.  
  289. static int do_mouse_move(int row, int col, PICKLIST *menu) {
  290.  
  291.      WNDPTR   *wnd;
  292.      MENU_WND *pwnd;
  293.      char     **wrk;
  294.      int      lcount, mpos;
  295.      int      barpos, off, cols;
  296.      int      fcolor, bcolor, cfclr, cbclr;
  297.  
  298. /* Dereference everything to make it easier to work with */
  299.  
  300.      pwnd   = &menu -> plwnd;
  301.      off    = menu -> off;
  302.      barpos = menu -> bar_pos;
  303.      cfclr  = pwnd -> cfclr; cbclr = pwnd -> cbclr;
  304.      fcolor = pwnd -> fcolor; bcolor = pwnd -> bcolor;
  305.  
  306.      wnd = pwnd -> wnd;
  307.      cols = (wnd -> lcol - wnd -> ucol) - 1;
  308.  
  309.      for(wrk = menu->list, lcount = -1; *wrk; wrk++, lcount++);
  310.  
  311.      if ((row > wnd -> urow && row < wnd -> lrow) &&
  312.          (col > wnd -> ucol && col < wnd -> lcol)) {
  313.          if (mpresent) hide_mouse();
  314.          row -= wnd -> urow+1;
  315.          mpos = row - barpos;
  316.          if ( mpos ) {
  317.             if ( off + mpos > lcount ) {
  318.                  if (mpresent) show_mouse();
  319.                  return ( -1 );
  320.             }
  321.             w_chg_attr(wnd,barpos+1,1,fcolor,bcolor,cols);
  322.             barpos += mpos;
  323.             w_chg_attr(wnd,barpos+1,1,cfclr,cbclr,cols);
  324.             off += mpos;
  325.          }
  326.          menu -> off = off;
  327.          menu -> bar_pos = barpos;
  328.          if (mpresent) show_mouse();
  329.          return ( off );
  330.      }
  331.      else if (row == wnd -> urow + 1) {
  332.         if ( col == wnd -> ucol ) move_bar_up( menu, 0 );
  333.         else if (col == wnd -> lcol) move_bar_down( menu, 0 );
  334.      }
  335.      return ( -1 );
  336. }
  337.